package org.micro.rbac.core.config;

import cn.hutool.core.util.StrUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * 跨域过滤器
 *
 * @author hongsir
 * @since 2023-07-25
 **/
@Slf4j
@Order(1)
@Component
@Configuration
public class MyCrossFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest httpRequest, HttpServletResponse httpResponse, FilterChain filterChain)
            throws ServletException, IOException {
        // 解决rest中文乱码问题
        httpRequest.setCharacterEncoding("utf-8");
        // 解决ajax跨域问题
        String origin = httpRequest.getHeader("origin");
        httpResponse.setHeader("Access-Control-Allow-Origin", StrUtil.blankToDefault(origin, "*"));
        httpResponse.setHeader("Access-Control-Request-Method", "GET,POST,HEAD,OPTIONS");
        httpResponse.setHeader("Access-Control-Request-Headers", "Token,x-requested-with,content-type,No-Cache");
        httpResponse.setHeader("Access-Control-Allow-Headers", "Token,x-requested-with,content-type,No-Cache");
        httpResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,HEAD,OPTIONS");
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
        // 跨域监测
        if (HttpMethod.OPTIONS.matches(httpRequest.getMethod())) {
            httpResponse.setStatus(HttpStatus.OK.value());
            httpResponse.setCharacterEncoding("UTF-8");
            httpResponse.getWriter().write("SUCCESS");
            return;
        }
        /**
         * PS:如果在此处转换,会导致POST接口@RequestBody注解序列化异常,顾在需要转换的拦截器或AOP进行转换即可
         * -new PostRequestWrapper(httpRequest);
         * -new GetRequestWrapper(httpRequest);
         */
        // POST 如果需要被下游读取参数,则需要做类型转换
//        PostRequestWrapper postWrapper = null;
//        GetRequestWrapper getWrapper = null;
//        if (HttpMethod.POST.matches(httpRequest.getMethod())) {
//            postWrapper = new PostRequestWrapper(httpRequest);
//        } else if (HttpMethod.GET.matches(httpRequest.getMethod())) {
//            getWrapper = new GetRequestWrapper(httpRequest);
//        }
//        // 执行下一个过滤器
//        filterChain.doFilter(postWrapper != null ? postWrapper : (getWrapper != null ? getWrapper : httpRequest), httpResponse)

        filterChain.doFilter(httpRequest, httpResponse);
    }
}
